<?php
namespace App\TxSchool\Type;

use App\TxSchool\Exceptions\UnknownTypeException;
use GuzzleHttp\Client;

abstract class Type{

    protected $defaultParams = [];
    protected $queryParams = [];
    protected $key;

    protected $baseUrl = "https://open.campus.qq.com/api/";
    protected $apiGetDepartmentInfoList = "open/getDepartmentInfoList";
    protected $apiGetObjectInfo = "open/getObjectInfo";
    protected $apiGetDepartInfoById ="open/getDepartInfoById";
    protected $apiGetAdminList ="open/getAdminList";
    protected $apiSearchUser = "common/searchUser";
    protected $apiGetUserInfo = "open/getUserInfo";
    protected $apiGetDepartAdminList = "schAdminInfo/getDepartAdminList";
    protected $apiGetAdminInfo = "open/getAdminInfo";
    protected $apiGetManageDepartList = "open/getManageDepartList";
    protected $apiGetParentRelation = "open/getParentRelation";
    protected $apiParentList  ="userInfo/parentList";
    protected $apiGetUpdateUser = "open/getUpdateUser";
    protected $apiGetUpdateDepart = "open/getUpdateDepart";
    protected $apiGetUpdateParentRelation = "open/getUpdateParentRelation";
    protected $apiGetObjList = "dutyConfig/getObjList";
    protected $apiSearchUserByParams = "open/searchUser";
    protected $apiGetUserFaceImage = "open/GetUserFaceImage";


    const DEV_TYPE_SCHOOL = 2;
    const DEV_TYPE_PARENT = 1;
    const DEV_TYPE_CO = 3;
    const DEV_TYPE_DEV = 5;


    const USER_TYPE_STUDENT = 1;
    const USER_TYPE_TEACHER = 2;
    const USER_TYPE_PARENT = 3;
    const USER_TYPE_OLD_BOY = 4;
    const USER_TYPE_RETIRE_TEACHER = 5;
    const USER_TYPE_OTHER = 6;

    const OBJECT_TYPE_SCHOOL = 2;
    const OBJECT_TYPE_PARENT = 1;

    public function __get($name)
    {
        return $this->defaultParams[$name] ?? null;
    }

    public function __set($name, $value)
    {
        $this->defaultParams[$name] = $value;
    }

    public function get($name){
        return $this->defaultParams[$name] ?? null;
    }

    public function set($name,$value){
        $this->defaultParams[$name] = $value;
    }

    public function setQueryParams($name,$value){
        $this->queryParams[$name] = $value;
    }

    /**
     * @param int $page
     * @param int $size
     * @param int $userType
     * @return mixed
     * @throws UnknownTypeException
     * 获取组织机构信息
     */
    public  function getDepartmentInfoList($page=1,$size = 30,$userType = self::USER_TYPE_TEACHER){
        $this->setQueryParams("page",$page);
        $this->setQueryParams("size",$size);
        $this->setQueryParams("usertype",$userType);
        return $this->httpGet($this->url($this->apiGetDepartmentInfoList));
    }

    /**
     * @return mixed
     * @throws UnknownTypeException
     * 获取学校信息
     */
    public function getObjectInfo(){
        return $this->httpGet($this->url($this->apiGetObjectInfo));
    }

    /**
     * @param $departid
     * @return mixed|null
     * 获取组织架构信息
     */
    public function getDepartInfoById($departid){
        $this->setQueryParams("departid",$departid);
        return $this->get($this->url($this->apiGetDepartInfoById));
    }

    /**
     * @param $userid
     * @param $usertype
     * @return mixed|null
     * 通过学生/家长id查询其家长/孩子信息
     */
    public function getParentRelation($userid,$usertype){
        $this->setQueryParams("userid",$userid);
        $this->setQueryParams("usertype",$usertype);
        return $this->get($this->url($this->apiGetParentRelation));
    }

    /**
     * @param $userid
     * @return mixed|null
     * 通过家长id查询孩子信息
     */
    public function getChildrenByUserId($userid){
        return $this->getParentRelation($userid,self::USER_TYPE_PARENT);
    }

    /**
     * @param $userid
     * @return mixed|null
     * 通过孩子id查询家长信息
     */
    public function getParentByUserId($userid){
        return $this->getParentRelation($userid,self::USER_TYPE_STUDENT);
    }

    /**
     * @param null $objectid
     * @param null $objType
     * @return mixed
     * @throws UnknownTypeException
     * 获取学校管理员列表
     */
    public function getAdminList($objectid = null,$objType = null){
        if($objectid){
            $this->setQueryParams("objectid",$objectid);
        }
        if($objType){
            $this->setQueryParams("objType",$objType);
        }
        return $this->httpGet($this->url($this->apiGetAdminList));
    }

    /**
     * @param $userid
     * @return mixed
     * @throws UnknownTypeException
     * 根据老师ID获取所管理的班级列表
     */
    public function getManageDepartList($userid){
        $this->setQueryParams("userid",$userid);
        return $this->httpGet($this->url($this->apiGetManageDepartList));
    }

    /**
     * @param $userid
     * @return mixed
     * @throws UnknownTypeException
     * 通过用户id验证用户是否为学校管理员
     */
    public function getAdminInfo($userid){
        $this->setQueryParams("userid",$userid);
        return $this->httpGet($this->url($this->apiGetAdminInfo));
    }

    /**
     * @param $departid
     * @return mixed
     * @throws UnknownTypeException
     * 根据班级id获取班级管理员列表
     */
    public function getDepartAdminList($departid){
        $this->setQueryParams("departid",$departid);
        return $this->httpGet($this->url($this->apiGetDepartAdminList));
    }

    /**
     * @param $departid
     * @param int $page
     * @param int $size
     * @return mixed
     * @throws UnknownTypeException
     * 通过学生组织架构id查询家长列表
     */
    public function parentList($departid,$page = 1,$size = 30){
        $this->setQueryParams("departid",$departid);
        $this->setQueryParams("page",$page);
        $this->setQueryParams("size",$size);
        return $this->httpGet($this->url($this->apiParentList));
    }

    /**
     * @param $dayNum
     * @return mixed
     * @throws UnknownTypeException
     * 获取用户变更列表
     */
    public function getUpdateUser($dayNum = null){
        $this->setQueryParams("dayNum",$dayNum);
        return $this->httpGet($this->url($this->apiGetUpdateUser));
    }

    /**
     * @param $dayNum
     * @return mixed
     * @throws UnknownTypeException
     * 获取组织架构变更列表
     */
    public function getUpdateDepart($dayNum = null){
        $this->setQueryParams("dayNum",$dayNum);
        return $this->httpGet($this->url($this->apiGetUpdateDepart));
    }


    /**
     * @param $dayNum
     * @return mixed
     * @throws UnknownTypeException
     * 获取组织架构变更列表
     */
    public function getUpdateParentRelation($dayNum = null){
        $this->setQueryParams("dayNum",$dayNum);
        return $this->httpGet($this->url($this->apiGetUpdateParentRelation));
    }

    /**
     * @return mixed
     * @throws UnknownTypeException
     * 获取职位列表（用于查询/写入教师信息时，对照教师职位）
     */
    public function getObjList(){
        return $this->httpGet($this->url($this->apiGetObjList));
    }

    /**
     * @param $searchtype
     * @param $keyword
     * @param null $usertype
     * @return mixed
     * @throws UnknownTypeException
     */
    public function SearchUserByParams($searchtype,$keyword,$usertype=null){
        $this->setQueryParams("searchtype",$searchtype);
        $this->setQueryParams("keyword",$keyword);
        $this->setQueryParams("usertype",$usertype);
        return $this->httpGet($this->url($this->apiSearchUserByParams));
    }

    /**
     * @param $usertype
     * @param $departid
     * @param $level
     * @param int $page
     * @param int $pageSize
     * @param null $key
     * @return mixed
     * @throws UnknownTypeException
     * 获取老师、学生、退休老师、校友等用户列表数据,支持按关键字进行搜索（关键字搜索频率限制为1秒1次）
     */
    public function searchUser($usertype,$departid,$level,$page = 1,$pageSize = 30, $key = null){
        $this->setQueryParams("usertype",$usertype);
        $this->setQueryParams("departid",$departid);
        $this->setQueryParams("level",$level);
        $this->setQueryParams("page",$page);
        $this->setQueryParams("pageSize",$pageSize);
        $this->setQueryParams("key",$key);
        return $this->httpGet($this->url($this->apiSearchUser));
    }

    /**
     * @param $departid
     * @param $level
     * @param int $page
     * @param int $pageSize
     * @param null $key
     * @return mixed
     * @throws UnknownTypeException
     */
    public function searchTeacher($departid,$level,$page = 1,$pageSize=30, $key = null){
        return $this->searchUser(self::USER_TYPE_TEACHER, $departid,$level,$page,$pageSize, $key );
    }
    /**
     * @param $departid
     * @param $level
     * @param int $page
     * @param int $pageSize
     * @param null $key
     * @return mixed
     * @throws UnknownTypeException
     */
    public function searchStudent($departid,$level,$page = 1,$pageSize=30, $key = null){
        return $this->searchUser(self::USER_TYPE_STUDENT, $departid,$level,$page,$pageSize, $key );
    }
    /**
     * @param $departid
     * @param $level
     * @param int $page
     * @param int $pageSize
     * @param null $key
     * @return mixed
     * @throws UnknownTypeException
     */
    public function searchOldBoy($departid,$level,$page = 1,$pageSize=30, $key = null){
        return $this->searchUser(self::USER_TYPE_OLD_BOY, $departid,$level,$page,$pageSize, $key );
    }
    /**
     * @param $departid
     * @param $level
     * @param int $page
     * @param int $pageSize
     * @param null $key
     * @return mixed
     * @throws UnknownTypeException
     */
    public function searchRetireTeache($departid,$level,$page = 1,$pageSize=30, $key = null){
        return $this->searchUser(self::USER_TYPE_RETIRE_TEACHER, $departid,$level,$page,$pageSize, $key );
    }
    /**
     * @param $departid
     * @param $level
     * @param int $page
     * @param int $pageSize
     * @param null $key
     * @return mixed
     * @throws UnknownTypeException
     */
    public function searchOther($departid,$level,$page = 1,$pageSize=30, $key = null){
        return $this->searchUser(self::USER_TYPE_OTHER, $departid,$level,$page,$pageSize, $key );
    }

    /**
     * @param $userid
     * @return mixed
     * @throws UnknownTypeException
     * 获取用户信息
     */
    public function getUserInfo($userid){
        $this->setQueryParams("userid",$userid);
        return $this->httpGet($this->url($this->apiGetUserInfo));

    }

    /**
     * @param $users
     * @return mixed
     * @throws UnknownTypeException
     */
    public function getFaceImage($users){
        if (is_array($users)){
            $str =  implode(',',$users);
        }else {
            $str = $users;
        }
        $this->setQueryParams('users', $str);
        return $this->httpGet($this->url($this->apiGetUserFaceImage));
    }

    /**
     * @param $api
     * @return string
     * 生成完整url
     */
    private function url($api){
        return $this->baseUrl.$api."?".$this->generateSign();
    }


    /**
     * @param $res
     * @return mixed
     * @throws UnknownTypeException
     */
    protected function format($res){
        $type =  config("school.responseType","array");
        if($type === "array"){
            return json_decode($res,true);
        }
        if($type === "object"){
            return json_decode($res);
        }
        throw new UnknownTypeException();
    }

    /**
     * @param $uri
     * @return mixed
     * @throws UnknownTypeException
     * get 请求
     */
    protected function httpGet($uri){
        $client = new Client();
        $response = $client->get($uri);
        return $this->format($response->getBody());

    }

    /**
     * @param $uri
     * @return mixed
     * @throws UnknownTypeException
     * post 请求
     */
    protected function httpPost($uri){
        $client = new Client();
        $response = $client->post($uri);
        return $this->format($response->getBody());
    }




    /**
     * @return string
     * 生成query参数/包含签名
     */
    protected function generateSign(){
        $signData = array_merge($this->defaultParams,$this->queryParams);
        $this->reset();
        $signData["timestamp"] = time();
        if (is_array($signData)) {
            $urlstr = urldecode(http_build_query($signData));
            $urlarr = explode('&', $urlstr);
        }
        sort($urlarr, SORT_STRING);
        $arg = implode('&', $urlarr);
        $sinArg = $arg."&key=".$this->key;
        $sign = strtoupper(md5($sinArg));//把最终的字符串签名，获得签名结果
        return $arg."&sign=". $sign;
    }

    /**
     * 清空查询参数
     */
    protected function reset(){
        $this->queryParams = [];
    }
}
